home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 3 / BBS in a box - Trilogy III.iso / Files / Prog / S / SERIAL.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1991-11-07  |  5.5 KB  |  233 lines  |  [TEXT/MSWD]

  1. { Serial Demo program adapted from SerialDemo.c by Mark Y. Geschelin. }
  2. { This program uses the modem port to send and recieve characters. }
  3. { It functions as a very simple terminal emulator.  This is meant to be an }
  4. { example of the use of the Serial Manager, not an example of how to code }
  5. { a terminal emulator!! }
  6. { Compile this program with Runtime.lib, Interface.lib, and Serial.p }
  7. { Pascal port by Phil Shapiro and Mark Y. Geschelin, ) 1990 Symantec Corp. }
  8. {  Revised: }
  9. {        7-03-90    Myg    Added handshaking and made buffer larger as well as some special}
  10. {                            processing because I found the default behavior really annoying during testing}
  11. {        9-26-91    PLS    Fixed to use OpenDriver instead of RAMSDOpen, other various aesthetic}
  12. {                            improvements.  Also added "back tic" escape route for old macs. }
  13.  
  14. program SerialDemo;
  15.     uses
  16.         Serial;
  17.     const
  18.         EscapeChar = Chr($1B);
  19.         BackTicChar = '`';
  20.         LinefeedChar = $0A;
  21.         BackspaceChar = $08;
  22.         DeleteChar = $7F;
  23.         Echo = FALSE;
  24.         recieveRaw = FALSE;        { Set this to true to see the raw data as sent }
  25.         transmitRaw = FALSE;        { Set this to true to send the data exactly as typed }
  26.         BufferLen = 1024;
  27.         xonchar = Chr($11);
  28.         xoffchar = Chr($13);
  29.         hatchar = $5E;
  30.         OutDriverName = '.AOut';
  31.         InDriverName = '.AIn';
  32.     type
  33.         BufferType = packed array[1..BufferLen] of SignedByte;
  34.         BufferPtr = ^BufferType;
  35.     var
  36.         inBuf: BufferPtr;                        { our buffer }
  37.         serialManagerBuffer: BufferPtr;    { the buffer for the serial manager }
  38.         inRefNum, outRefNum: integer;
  39.  
  40.     function AvailChar: Char;            { poll for data from keyboard }
  41.         var
  42.             c: Char;
  43.             event: EventRecord;
  44.  
  45.         function InterpretOutput (x: SignedByte): Char;
  46.         begin
  47.             if transmitRaw then
  48.                 InterpretOutput := Char(x)
  49.             else
  50.                 case x of
  51.                     BackspaceChar: 
  52.                         InterpretOutput := Char(DeleteChar);
  53.                     LinefeedChar: 
  54.                         ;
  55.                     otherwise
  56.                         InterpretOutput := Char(x);
  57.                 end;
  58.         end;
  59.  
  60.     begin
  61.         c := Char(0);
  62.         if GetNextEvent(everyevent, event) then
  63.             if (event.what = keyDown) or (event.what = autoKey) then
  64.                 c := InterpretOutput(BAND(event.message, charCodeMask));
  65.         AvailChar := c;
  66.     end;
  67.  
  68.     procedure CleanUp;
  69.         var
  70.             dummy: OSErr;
  71.     begin
  72.         if inbuf <> nil then
  73.             dispose(inbuf);
  74.         if serialManagerBuffer <> nil then
  75.             dispose(serialManagerBuffer);
  76.         if inRefNum <> 0 then
  77.             dummy := CloseDriver(inRefNum);
  78.         if outRefNum <> 0 then
  79.             dummy := CloseDriver(outRefNum);
  80.     end;
  81.  
  82.     procedure DisplayBuff (count: Longint);
  83.         var
  84.             i: Longint;
  85.             hatflag: boolean;
  86.  
  87.         procedure Interpret (x: SignedByte);
  88.         begin
  89.             if hatflag then
  90.                 hatflag := false
  91.             else
  92.                 begin
  93.                     if recieveRaw then
  94.                         write(Char(x))
  95.                     else
  96.                         case x of
  97.                             LinefeedChar, BackspaceChar: 
  98.                                 ;
  99.                             hatchar: 
  100.                                 hatflag := true;
  101.                             otherwise
  102.                                 write(Char(x));
  103.                         end;
  104.                 end;
  105.         end;
  106.  
  107.     begin
  108.         hatflag := false;
  109.         for i := 1 to count do
  110.             Interpret(inbuf^[i]);
  111.     end;
  112.  
  113.     procedure GetSerialChars (count: Longint);
  114.         var
  115.             err: OSErr;
  116.     begin
  117.         err := FSRead(inRefNum, count, Ptr(inbuf));
  118.     end;
  119.  
  120.     function SerialCharsAvail: integer;
  121.         var
  122.             count: Longint;
  123.             err: OSErr;
  124.     begin
  125.         err := SerGetBuf(inRefNum, count);
  126.         SerialCharsAvail := count
  127.     end;
  128.  
  129.     procedure SerialWrite (ch: Char);
  130.         var
  131.             err: OSErr;
  132.             num: Longint;
  133.             cha: SignedByte;
  134.     begin
  135.         num := 1;
  136.         cha := SignedByte(ch);
  137.         err := FSWrite(outRefNum, num, @cha);
  138.     end;
  139.  
  140.     function SerialInit: OSErr;
  141.         var
  142.             err: OStErr;
  143.             flags: SerShk;
  144.  
  145.         procedure FailOSErr (err: OSErr);
  146.         begin
  147.             if err <> noErr then
  148.                 begin
  149.                     SerialInit := err;
  150.                     exit(SerialInit);
  151.                 end;
  152.         end;
  153.  
  154.     begin
  155.         outRefNum := 0;
  156.         inRefNum := 0;
  157.         serialManagerBuffer := nil;
  158.         inbuf := nil;
  159.         SerialInit := noErr;
  160.         with flags do
  161.             begin
  162.                 fxon := byte(TRUE);
  163.                 finx := byte(TRUE);
  164.                 xon := xonchar;
  165.                 xoff := xoffchar;
  166.             end;
  167.         new(serialManagerBuffer);
  168.         new(inbuf);
  169.         FailOSErr(OpenDriver(OutDriverName, outRefNum));
  170.         FailOSErr(OpenDriver(InDriverName, inRefNum));
  171.         FailOSErr(SerReset(outRefNum, baud2400 + data8 + stop10 + noParity));
  172.         FailOSErr(SerReset(inRefNum, baud2400 + data8 + stop10 + noParity));
  173. { make a large input buffer }
  174.         FailOSErr(SerSetBuf(inRefNum, Ptr(serialManagerBuffer), Sizeof(BufferType)));
  175. { and even with the large input buffer set it up so it will send an xoff when the buffer is full }
  176. { see the flags structure }
  177.         FailOSErr(SerHShake(inRefNum, flags));
  178.     end;
  179.  
  180.     procedure Introduction;
  181.         var
  182.             r: Rect;
  183.     begin
  184.         SetRect(r, 5, 40, 500, 310);
  185.         SetTextRect(r);
  186.         ShowText;
  187.         writeln('This program reads and writes to the modem port at 2400 baud.');
  188.         writeln('It uses these protocols:  8 data bits, 1 stop bits, and no parity.');
  189.         writeln('Press the ESC (or `) key to exit.');
  190.     end;
  191.  
  192.     procedure Main;
  193.         var
  194.             err: OSErr;
  195.             count: Integer;
  196.             ch: Char;
  197.     begin
  198.         err := SerialInit;
  199.         if err = noErr then
  200.             begin
  201.                 ch := AvailChar;
  202.                 while (ch <> EscapeChar) and (ch <> BackTicChar) do
  203.                     begin
  204.                         if Ord(ch) <> 0 then
  205.                             begin
  206.                                 SerialWrite(ch);
  207.                                 if echo then
  208.                                     write(ch)
  209.                             end;
  210.                         count := SerialCharsAvail;
  211. { see what happens if you comment out the SerHShake and leave this code in }
  212. {    if count > (bufferlen div 2) then }
  213. {    begin }
  214. {    writeln; }
  215. {    writeln('were are getting full warning count =', count, ' if this = buflen-1 chances are we overran'); }
  216. {    end; }
  217.                         if count <> 0 then
  218.                             begin
  219.                                 GetSerialChars(count);
  220.                                 DisplayBuff(count)
  221.                             end;
  222.                         ch := AvailChar;
  223.                     end;     {while}
  224.             end
  225.         else
  226.             writeln('The serial initializations have failed, id = ', err);
  227.     end;
  228.  
  229. begin
  230.     Introduction;
  231.     Main;
  232.     CleanUp
  233. end